import { Answer } from "./db.js";
import { jsonToString, stringToJson, catchAwait } from "utils-lib-js-lite";
import fs from "fs";
import { IExpressMiddlewareFn } from "./types.js";
import { responseMiddleware } from "./middleware.js";
import { baseMessage } from "./config.js";
export type IAnswer = {
  id: number;
  label: string;
  return: string;
  name: string;
  value: string;
  showAll?: boolean;
};
export type IAnswerList = Partial<IAnswer>[];
type IBackup = Record<string, IAnswerList>;
const DBName = "answer";
export class AnswerController {
  readonly maxIdCount = 100;

  constructor() {
    // 重启服务时会将数据库文件刷新到本地，此外数据库更新后也会刷新到本地,备份数据
    this.syncData();
    this.backup();
  }
  // 同步获取本地文件
  getAnswerList(path: string = "./answer/main") {
    const file = fs.readFileSync(path, { encoding: "utf-8" });
    return stringToJson(file) ?? ([] as IAnswerList);
  }
  // 设置本地文件
  setAnswerList(val, path: string = "./answer/main") {
    if (typeof val !== "string") val = jsonToString(val);
    fs.writeFileSync(path, val, { encoding: "utf-8" });
  }
  // 创建id
  createId(answer: IAnswerList, key: string = "id") {
    answer.sort((a, b) => a[key] - b[key]);
    const last = answer[answer.length - 1];
    const id = (last?.[key] ?? 0) + 1;
    return id > this.maxIdCount ? -1 : id;
  }
  hasSameValue(list, answer) {
    return list.find(
      (it) => it.value === answer.value || it.name === answer.name
    );
  }
  // 存数据库
  async save(answer) {
    const list = await this.get();
    const hasItem = this.hasSameValue(list, answer);
    if (hasItem) return Promise.reject("关键字或值重复");
    const id = answerController.createId(list);
    if (id < 0)
      return Promise.reject(
        `关键字达到数量限制${answerController.maxIdCount}条，请删除后再添加`
      );
    list.push({ ...answer, id });
    await Answer.put(DBName, list);
    return Promise.resolve();
  }
  // 获取全部回复信息
  async getAllMESSAGE() {
    const list = await this.get();
    return baseMessage.concat(list);
  }
  // 获取数据库信息
  async get(ids?: (string | number)[]) {
    const list =
      (await Answer.get<IAnswerList>(DBName))?.filter((it) => it) ?? [];
    if (!ids) return list;
    return list.filter((it) => ids.includes(it.id.toString()));
  }

  // 删除数据库信息
  async delete(id: string | number) {
    const list = await this.get();
    const hasItem = list.find((it) => it.id?.toString() === id?.toString());
    if (!hasItem) return Promise.reject("未找到删除项");
    await Answer.put(
      DBName,
      list?.filter((it) => it.id?.toString() !== id?.toString())
    );
    return Promise.resolve();
  }

  // 修改数据库某项
  async edit(answer) {
    const list = await this.get();
    const hasItem = this.hasSameValue(
      list.filter((it) => it.id?.toString() !== answer.id?.toString()),
      answer
    );
    if (hasItem) return Promise.reject("关键字或值重复");
    const index = list.findIndex(
      (it) => it.id?.toString() === answer.id?.toString()
    );
    if (index < 0) return Promise.reject("未找到修改项");
    list[index] = {
      ...list[index],
      ...answer,
    };
    await Answer.put(DBName, list);
    return Promise.resolve();
  }
  // 备份数据库信息
  async backup() {
    const answer = await this.get();
    const path = "./answer/backup";
    const file = (this.getAnswerList(path) as unknown as IBackup) ?? {};
    const key = new Date().toLocaleString();
    file[key] = answer;
    this.setAnswerList(file, path);
  }

  async syncData() {
    const metaData = await this.get();
    metaData && this.setAnswerList(metaData);
  }
}
export const answerController = new AnswerController();

const createAnswer: IExpressMiddlewareFn<
  unknown,
  unknown,
  IAnswer,
  IAnswer
> = async (req, res, next) => {
  // 增加
  const { body } = req;
  if (!body) return responseMiddleware(res, { msg: "参数错误" });
  const [err] = await catchAwait(answerController.save(body));
  if (err) return responseMiddleware(res, { msg: err });
  return responseMiddleware(res, { msg: "添加成功" });
};
const deleteAnswer: IExpressMiddlewareFn<
  unknown,
  unknown,
  IAnswer,
  IAnswer
> = async (req, res, next) => {
  // 删除
  const { query } = req;
  if (!query || !query.id) return responseMiddleware(res, { msg: "参数错误" });
  const [err] = await catchAwait(answerController.delete(query.id));
  if (err) return responseMiddleware(res, { msg: err });
  return responseMiddleware(res, { msg: "删除成功" });
};

const editAnswer: IExpressMiddlewareFn<
  unknown,
  unknown,
  IAnswer,
  IAnswer
> = async (req, res, next) => {
  // 修改
  const { body } = req;
  if (!body || !body.id) return responseMiddleware(res, { msg: "参数错误" });
  const [err] = await catchAwait(answerController.edit(body));
  if (err) return responseMiddleware(res, { msg: err });
  return responseMiddleware(res, { msg: "修改成功" });
};
export const answerMiddleware: IExpressMiddlewareFn<
  unknown,
  unknown,
  IAnswer,
  IAnswer
> = async (req, res, next) => {
  const { method, query } = req;
  if (method === "POST") {
    // 新增
    return createAnswer(req, res, next);
  } else if (method === "DELETE") {
    // 删除
    return deleteAnswer(req, res, next);
  } else if (method === "PUT") {
    // 修改
    return editAnswer(req, res, next);
  }
  // 查询
  const list: IAnswerList =
    (await (query.showAll
      ? answerController.getAllMESSAGE()
      : answerController.get())) ?? [];
  return responseMiddleware(res, jsonToString(list));
};
